/*
 * 指针和引用
 * 对指针来说，解构(destructure)和解引用(dereference) 要去分开，因为这两者的概念是
 * 不同的，和C 那样的语言用法不同
 * - 解引用使用`*`
 * - 解构使用 `&`, `ref` 和 `ref mut`
 */
fn main() {
    // 获得一个`i32`类型的引用。`&`表示取引用
    let reference = &4;

    match reference {
        // 如果用`&val`这个模式去匹配`reference` ，就相当于做这样的比较
        // `&i32` (即 `reference`的类型)
        // `&val`(即 用于匹配的模式)
        // 因此可用 `val`表示被 `reference` 引用的值4
        &val => println!("Got a value via destructuring: {:?}", val),
    }

    // 如果不想用 `&`，需要在匹配前解引用
    match *reference {
        val => println!("Got a value via dereferencing: {:?}", val),
    }

    // 如果一开始就不用引用，会怎样？`reference`是一个`&`类型，因为赋值语句的
    // 右边已经是一个引用。但下面这个不是引用，因为右边不是
    let _not_a_reference = 3;

    // Rust 对这种情况提供了 `ref` 它更改了赋值的行为，从而可以对具体值创建引用
    // 下面这个行将得到一个引用
    let ref _is_a_reference = 3;

    // 相应地，定义两个非引用的变量，通过`ref`, `ref mut` 仍可取得其引用
    let value = 5;
    let mut mut_value = 6;

    // 使用 `ref` 关键字来创建引用
    // 下面的`r`是`&i32`类型
    match value {
        ref r => println!("Got a reference to a value: {:?}", r),
    }

    // 类似地使用`ref mut`
    match mut_value {
        ref mut m => {
            // 已经获得了`mut_value`的引用，先要解引用，才能改变它的值
            *m += 10;
            println!("We added 10, `mut_value`: {:?}", m);
        }
    }
}